package core.proto;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

public class SearchBar extends JPanel
{
	private static final long serialVersionUID = -4698815339116283668L;
	private Component parent;
	private JLabel searchLabel;
	JTextField searchField;
	private boolean isSearchStarted;
//	private JButton searchButton;
	
	public SearchBar(Component parent) {
		this.parent = parent;
		isSearchStarted = false;
		searchLabel = new JLabel("Search:");
		searchLabel.setFont(new Font("Courier New", Font.BOLD, 12));
		searchField = new JTextField(18);
		if (parent instanceof AllComponents) {
			searchField.addKeyListener(new SearchTableKeyAdapter());	
			this.setLayout(new BorderLayout());
			this.setPreferredSize(new Dimension(150, 40));
			this.add(searchLabel, BorderLayout.NORTH);
			this.add(searchField, BorderLayout.SOUTH);
			
		} else if (parent instanceof FileTree) {
			searchField.addKeyListener(new SearchTreeKeyAdapter());
			this.myTree = ((FileTree)parent).tree;
		    this.myRoot = (DefaultMutableTreeNode) myTree.getModel().getRoot();
			this.setPreferredSize(new Dimension(150, 50));
			this.add(searchLabel, BorderLayout.WEST);
			this.add(searchField, BorderLayout.EAST);
//			this.setLayout(new FlowLayout());
//			this.add(searchLabel);
//			this.add(searchField);
		}			
//		searchButton = new JButton("Search");
//		searchButton.setSize(30, 20);
//		searchButton.addMouseListener((MouseListener)new SearchMouseListener());
	}
	
	
	/**********************************************************************
	 * SearchBar for History Table
	 **********************************************************************/
	class SearchTableKeyAdapter extends KeyAdapter {
		public void keyReleased(KeyEvent e) {
			JTextField textField = (JTextField) e.getSource();
			String searchStr = textField.getText();
			Set<String> highlightTxtSet = new HashSet<String>();
			highlightTxtSet.add(searchStr);
			AllComponents.getHistoryRenderer().loadData(highlightTxtSet, searchStr);
		}
	}
	
	
	/**********************************************************************
	 * SearchBar for Director Tree
	 **********************************************************************/
	private JTree myTree;
	private DefaultMutableTreeNode myRoot;
	
	public JTextField getSearchField() {
		return this.searchField;
	}
	
	public DefaultMutableTreeNode searchNode(String nodeStr) {
		if (nodeStr == null | nodeStr.length() == 0) return null;
		
		DefaultMutableTreeNode node = null;
		Enumeration e = myRoot.breadthFirstEnumeration();
		while (e.hasMoreElements()) {
			node = (DefaultMutableTreeNode) e.nextElement();
			if (node.getUserObject().toString().toLowerCase().indexOf(nodeStr.toLowerCase()) != -1) {
				return node;
			}
		}
		return null;
	}
	
	public DefaultMutableTreeNode[] matchedNodes = null;
	
	public DefaultMutableTreeNode[] searchAllNode(String nodeStr) {
		if (nodeStr == null | nodeStr.length() == 0) return null;

		matchedNodes = null;
		List<DefaultMutableTreeNode> nodeList = new ArrayList<DefaultMutableTreeNode>();
		Enumeration e = myRoot.breadthFirstEnumeration();
		while (e.hasMoreElements()) {
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.nextElement();
			IconData data = (IconData) node.getUserObject();
			if (node.getUserObject().toString().toLowerCase().indexOf(nodeStr.toLowerCase()) != -1) {				
				data.m_backgroudColor = FileTree.SEARCHED_NODE_BACKGROUND_COLOR;
//				System.out.println(">>>>>>>>>>>>data.m_backgroudColor = Color.YELLOW");
				nodeList.add(node);
			} else {
				data.m_backgroudColor = Color.WHITE;
			}
		}
		if (nodeList.size() > 0) {
			DefaultMutableTreeNode[] nodeArray = new DefaultMutableTreeNode[nodeList.size()];
			nodeList.toArray(nodeArray);
			matchedNodes = nodeArray;
			return nodeArray;
		}
		
		return null;
	}
	  
	public void removeHighlight(DefaultMutableTreeNode[] matchedNodes) {
		if (matchedNodes == null | matchedNodes.length == 0) return;

		for (DefaultMutableTreeNode node : matchedNodes) {
			IconData data = (IconData) node.getUserObject();
			data.m_backgroudColor = Color.WHITE;
		}
	}
	
	public boolean isSearchStarted(){
	    return isSearchStarted;
	}
	  
	class SearchTreeKeyAdapter extends KeyAdapter {
		public void keyReleased(KeyEvent e) {
			System.out.println("Search tree ...");
			
			// If it begins searching, save current tree expanded status
			if (!isSearchStarted) {
				((FileTree)parent).saveTreeExpandedStatus();
				isSearchStarted = true;
			}

			// collapse the tree before searching
		    int rowCount = myTree.getRowCount() - 1;
		    while (rowCount >= 0) {
		    	myTree.collapseRow(rowCount);
		    	rowCount--;
		    }
		    
			// If it's the end of searching, then restore the tree to it's original expanded status
			String searchText = searchField.getText();
		    if (searchText == null || searchText.length() == 0) {
		    	removeHighlight(matchedNodes);
				((FileTree)parent).restoreExpandedTreeStatus();
				isSearchStarted = false;
		    	return;
		    }
		    
		    // Do search
	        DefaultMutableTreeNode[] nodeArray = searchAllNode(searchText);
	        if (nodeArray != null && nodeArray.length > 0) {
		        for (DefaultMutableTreeNode node : nodeArray) {
		        	TreeNode[] nodes = ((DefaultTreeModel)myTree.getModel()).getPathToRoot(node);
		        	TreePath path = new TreePath(nodes);
		        	myTree.scrollPathToVisible(path);
//		        	myTree.setSelectionPath(path);
		        }
	        } else {
	        	System.out.println("Node with string " + searchText + " not found");
	        }
		}
	}
}